﻿#region Description
/*  File Name:      MenuEntry.cs
 *  Author:         Adam Goodchild
 *  
 *  Description:    This class is a single Menu Entry for a Menu System.
 *                  It handles the Drawing and Updating of the Menu Entry
 *  
 *  Sources:         The Idea for this class was gained from the following source(s):
 *                  Microsoft XNA Creators Club - Game State Management Sample
*/
#endregion

#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MinimizeEngine.Managers;
#endregion

namespace MinimizeEngine.Menu_System
{
    public class MenuEntry
    {
        #region Fields

        //TRY AND GET A CONFIG FILE THAT CAN SET WHAT OPTIONS YOU WANT HERE
        /// <summary>
        /// The Colour that the Text shall be drawn
        /// </summary>
        Color mColor;

        /// <summary>
        /// The Text that is displayed as the Menu Entry
        /// </summary>
        string mText;

        /// <summary>
        /// Stores the current Fading Effect on the Menu Entry
        /// </summary>
        float mSelectionFade;

        /// <summary>
        /// Determines whether the MenuEntry is animated or not
        /// </summary>
        bool m_bIsAnimated;

        /// <summary>
        /// Handles an Event Raised when the Menu Entry is Selected
        /// </summary>
        public event EventHandler<PlayerIndexEventArgs> Selected;
        
        #endregion

        #region Properties

        public string Text
        {
            get { return mText; }
            set{ mText = value; }
        }

        /// <summary>
        /// Get how much space this Menu Entry requires
        /// </summary>
        /// <param name="menuScreen"></param>
        /// <returns></returns>
        public virtual int GetHeight(MenuScreen menuScreen)
        {
            return menuScreen.ScreenManager.Font.LineSpacing;
        }

        #endregion

        #region Event Handling

        protected internal virtual void OnMenuEntrySelected(PlayerIndex playerIndex)
        {
            if(Selected != null)
            {
                Selected(this, new PlayerIndexEventArgs(playerIndex));
            }
        }
        
        #endregion

        #region Initialization

        /// <summary>
        /// Constructor for the Menu Entry.
        /// Takes in the Text to represent the Menu Entry
        /// </summary>
        /// <param name="menuText"></param>
        public MenuEntry(string menuText)
        {
            mText = menuText;
        }

        #endregion

        #region Update

        /// <summary>
        /// Update the Menu Entry
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="isSelected"></param>
        /// <param name="menuScreen"></param>
        public virtual void Update(GameTime gameTime, bool isSelected, MenuScreen menuScreen)
        {
            //Set the Animation bool
            m_bIsAnimated = menuScreen.IsAnimated;

            //Do some fancy Fading between a Selected and Deselected State
            float fadeSpeed = (float)gameTime.ElapsedGameTime.TotalSeconds * 4;

            if(isSelected)
            {
                mSelectionFade = Math.Min(mSelectionFade + fadeSpeed, 1);
            }
            else
            {
                mSelectionFade = Math.Max(mSelectionFade - fadeSpeed, 0);
            }
        }

        #endregion

        #region Draw

        public virtual void Draw(GameTime gameTime, MenuScreen menuScreen, Vector2 position, bool isSelected)
        {
            //What colour should the text be drawn?
            //This is based on whether the MenuEntry is selected (highlighted) or not
            mColor = isSelected ? Color.Yellow : Color.White;

            //Get the Screen Manager, SpriteBatch and Font
            ScreenManager screenManager = menuScreen.ScreenManager;
            SpriteBatch spriteBatch = screenManager.SpriteBatch;
            SpriteFont spriteFont = screenManager.Font;

            //Change the Alpha of the Texts Colour to fade out during Transition Stages
            mColor = new Color(mColor.R, mColor.G, mColor.B, menuScreen.TransitionAlpha);
            
            Vector2 textOrigin = new Vector2(0, spriteFont.LineSpacing / 2);

            //If true, Animate the Menu Font
            if(m_bIsAnimated)
            {
                double time = gameTime.TotalGameTime.TotalSeconds;

                float pulsate = (float)Math.Sin(time * 6) + 1;
                float scale = 1 + pulsate * 0.05f * mSelectionFade;

                spriteBatch.DrawString(spriteFont, mText, position, mColor, 0, textOrigin,
                    scale, SpriteEffects.None, 0);
            }
            else
            {
                spriteBatch.DrawString(spriteFont, mText, position, mColor);
            }
        }

        #endregion
    }

    #region PlayerIndexEventArgs Class
    /// <summary>
    /// Class to handle an event argument, and includes the PlayerIndex of who
    /// triggered the Event.
    /// </summary>
    public class PlayerIndexEventArgs : EventArgs
    {
        #region Fields

        PlayerIndex mPlayerIndex;

        #endregion

        #region Properties

        /// <summary>
        /// Get the PlayerIndex of who triggered the Event.
        /// </summary>
        public PlayerIndex PlayerIndex
        {
            get { return mPlayerIndex; }
        }

        #endregion

        #region Initialization

        public PlayerIndexEventArgs(PlayerIndex playerIndex)
        {
            mPlayerIndex = playerIndex;
        }
        
        #endregion
    }
    #endregion
}
